import { Spin } from 'antd';
import React, { memo, useEffect, useState } from 'react';
import { Menu, IObject, getHistory } from '@cscec/udp-ui';
import routeConfig from '../../../route';

const routeMap = new Map();

const menuClick = ({ key }: { key: string }) => {
  getHistory().push(key + routeMap.get(key).query);
};

function hasName(childRoutes: IObject[]): boolean {
  return childRoutes.some(({ children, routes, name }: any) => {
    if (name) return true;
    if (children || routes) {
      return hasName(children || routes);
    }
    return false;
  });
}

/**
 * 递归生成左侧菜单项
 * @param menus 菜单配置
 * @param key 唯一标识
 * @param parentKeys 父级keys
 */
const createMenuItems = (menus: IObject[], key = 'menu', parentKeys: any = []) => {
  const items: any = [];
  menus.forEach(({
    children, routes, path, name, query, icon, menuKey, hideInMenu,
  }, index) => {
    const itemKey = menuKey || path;
    if (name) {
      const menuChildren = children || routes;
      if (menuChildren && menuChildren.length > 0 && hasName(menuChildren)) {
        const mKey = `${key}_${index}`;
        items.push(
          <Menu.SubMenu key={mKey} title={name} icon={icon}>
            {createMenuItems(menuChildren, mKey, [...parentKeys, mKey])}
          </Menu.SubMenu>,
        );
      } else {
        const params = query ? Object.keys(query).reduce((p, key) => {
          const c = p ? `${p}&` : '?';
          return `${c}${key}=${query[key]}`;
        }, '') : '';
        routeMap.set(path, { parentKeys, query: params, key: itemKey });
        if (!hideInMenu) {
          items.push(
            <Menu.Item key={itemKey} icon={icon}>
              {name}
            </Menu.Item>,
          );
        }
      }
    } else if (menuKey) {
      routeMap.set(path, { parentKeys, query: '', key: menuKey });
    }
  });
  return items;
};

/**
 * 菜单初始状态
 * @param pathname 路由
 */
const initMenuSelected: any = (pathname: string) => {
  const route = routeMap.get(pathname) || {};
  return {
    selectKeys: [route.key ?? pathname] || [],
    openKeys: route.parentKeys || [],
  };
};

/**
 * 生成菜单及状态
 * @param pathname 路由
 * @param menus 菜单配置项
 */
const initMenus = (pathname: string, menus: IObject[]) => {
  const menuArray = createMenuItems(menus);
  return {
    menus: menuArray,
    ...initMenuSelected(pathname),
  };
};

/**
 * 导出左侧菜单树
 */
export default memo(({ pathname }: any) => {
  const [state] = useState(() => initMenus(pathname, routeConfig));

  const [selectedKeys, setSelectedKeys] = useState([pathname]);

  useEffect(() => {
    if (routeMap.has(pathname)) {
      setSelectedKeys([routeMap.get(pathname).key]);
    }
  }, [pathname]);

  return state.menus ? (
    <Menu
      theme="dark"
      mode="inline"
      selectedKeys={selectedKeys}
      defaultOpenKeys={state.openKeys}
      defaultSelectedKeys={state.selectKeys}
      onClick={menuClick}
    >
      {state.menus}
    </Menu>
  ) : (
    <div style={{ textAlign: 'center', marginTop: '20px' }}>
      <Spin />
    </div>
  );
});
